#ifndef ANAGRAM_OPTIMIZER_NGRAMTOOL_ISTRING_H
#define ANAGRAM_OPTIMIZER_NGRAMTOOL_ISTRING_H

#include <functional>
#include <limits>
#include <string>

namespace anagram_optimizer {

// An interned string.
//
// Strings are stored in a global, thread-safe table.
class istring {
 public:
  istring() : index_(kInvalid) {}

  // Implicit constructors for strings.
  istring(const std::string& s);
  istring(const char* s);  // Incurs a copy.

  const std::string& as_string() const;

  bool operator==(const istring& other) const {
    return index_ == other.index_;
  }

  bool operator!=(const istring& other) const {
    return index_ != other.index_;
  }

  istring& operator=(const istring& other) {
    index_ = other.index_;
    return *this;
  }

 private:
  static const size_t kInvalid = std::numeric_limits<size_t>::max();

  template<typename T>
  friend struct std::hash;

  size_t index_;
};

}  // namespace anagram_optimizer

namespace std {
template<>
struct hash<anagram_optimizer::istring> {
  size_t operator()(const anagram_optimizer::istring& g) const {
    std::hash<size_t> h;
    return h(g.index_);
  }
};
}  // namespace std

#endif // ANAGRAM_OPTIMIZER_NGRAMTOOL_ISTRING_H
